function [] = sm_adder_tb()
    % ci x y | ci+x+y  | co
    % ---------------------
    % 0  0 0 | 0+0+0=0 | 0
    % 0  0 1 | 0+0+1=1 | 0
    % 0  1 0 | 0+1+0=1 | 0
    % 0  1 1 | 0+1+1=0 | 1
    % 1  0 0 | 1+0+0=1 | 0
    % 1  0 1 | 1+0+1=0 | 1
    % 1  1 0 | 1+1+0=0 | 1
    % 1  1 1 | 1+1+1=1 | 1
    
    % ci x y | ci+x-y  | co
    % ---------------------
    % 0  0 0 | 0+0-0=0 | 0
    % 0  0 1 | 0+0-1=1 | 0
    % 0  1 0 | 0+1-0=1 | 0
    % 0  1 1 | 0+1-1=0 | 1
    % 1  0 0 | 1+0-0=1 | 0
    % 1  0 1 | 1+0-1=0 | 1
    % 1  1 0 | 1+1-0=0 | 1
    % 1  1 1 | 1+1-1=1 | 1

    % +++
    % ++-
    % -++
    % -+-
    % +-+
    % +--
    % --+
    % ---
    
    % +++
    %disp('+++');
    A = 89;
    A_sm = [0 0 1 0 1 1 0 0 1];
    B = 106;
    B_sm = [0 0 1 1 0 1 0 1 0];
    Z = sm_adder(A_sm,B_sm,0).*1;
    X = [0 1 1 0 0 0 0 1 1];
    t = convert_10base(Z);
    assert(A,B,'+',t,A_sm,B_sm,Z,X);

    A = 106;
    A_sm = [0 0 1 1 0 1 0 1 0];
    B = 89;
    B_sm = [0 0 1 0 1 1 0 0 1];
    Z = sm_adder(A_sm,B_sm,0).*1;
    X = [0 1 1 0 0 0 0 1 1];
    t = convert_10base(Z);
    assert(A,B,'+',t,A_sm,B_sm,Z,X);
    
    % ++-
    %disp('++-');
    A = 89;
    A_sm = [0 0 1 0 1 1 0 0 1];
    B = -106;
    B_sm = [1 0 1 1 0 1 0 1 0];
    X = [1 0 0 0 1 0 0 0 1];
    Z = sm_adder(A_sm,B_sm,0)*1;
    t = convert_10base(Z);
    assert(A,B,'+',t,A_sm,B_sm,Z,X);
    
    A = 106;
    A_sm = [0 0 1 1 0 1 0 1 0];
    B = -89;
    B_sm = [1 0 1 0 1 1 0 0 1];
    X = [0 0 0 0 1 0 0 0 1];
    Z = sm_adder(A_sm,B_sm,0)*1;
    t = convert_10base(Z);
    assert(A,B,'+',t,A_sm,B_sm,Z,X);

    % -++
    %disp('-++');
    A = -89;
    A_sm = [1 0 1 0 1 1 0 0 1];
    B = 106;
    B_sm = [0 0 1 1 0 1 0 1 0];
    X = [0 0 0 0 1 0 0 0 1];
    Z = sm_adder(A_sm,B_sm,0)*1;
    t = convert_10base(Z);
    assert(A,B,'+',t,A_sm,B_sm,Z,X);

    A = -106;
    A_sm = [1 0 1 1 0 1 0 1 0];
    B = 89;
    B_sm = [0 0 1 0 1 1 0 0 1];
    X = [1 0 0 0 1 0 0 0 1];
    Z = sm_adder(A_sm,B_sm,0)*1;
    t = convert_10base(Z);
    assert(A,B,'+',t,A_sm,B_sm,Z,X);

    % -+-
    %disp('-+-');
    A = -89;
    A_sm = [1 0 1 0 1 1 0 0 1];
    B = -106;
    B_sm = [1 0 1 1 0 1 0 1 0];
    X = [1 1 1 0 0 0 0 1 1];
    Z = sm_adder(A_sm,B_sm,0)*1;
    t = convert_10base(Z);
    assert(A,B,'+',t,A_sm,B_sm,Z,X);

    
    A = -106;
    A_sm = [1 0 1 1 0 1 0 1 0];
    B = -89;
    B_sm = [ 1 0 1 0 1 1 0 0 1];
    X = [1 1 1 0 0 0 0 1 1];
    Z = sm_adder(A_sm,B_sm,0)*1;
    t = convert_10base(Z);
    assert(A,B,'+',t,A_sm,B_sm,Z,X);

    % +-+
    %disp('+-+');
    A = 89;
    A_sm = [0 0 1 0 1 1 0 0 1];
    B = 106;
    B_sm = [0 0 1 1 0 1 0 1 0];
    X = [1 0 0 0 1 0 0 0 1];
    Z = sm_adder(A_sm,B_sm,1)*1;
    t = convert_10base(Z);
    assert(A,B,'-',t,A_sm,B_sm,Z,X);
    
    A = 106;
    A_sm = [0 0 1 1 0 1 0 1 0];
    B = 89;
    B_sm = [0 0 1 0 1 1 0 0 1];
    X = [0 0 0 0 1 0 0 0 1];
    Z = sm_adder(A_sm,B_sm,1)*1;
    t = convert_10base(Z);
    assert(A,B,'-',t,A_sm,B_sm,Z,X);

    % +--
    %disp('+--');
    A = 89;
    A_sm = [0 0 1 0 1 1 0 0 1];
    B = -106;
    B_sm = [1 0 1 1 0 1 0 1 0];
    X = [0 1 1 0 0 0 0 1 1];
    Z = sm_adder(A_sm,B_sm,1)*1;
    t = convert_10base(Z);
    assert(A,B,'-',t,A_sm,B_sm,Z,X);
    
    A = 106;
    A_sm = [0 0 1 1 0 1 0 1 0];
    B = -89;
    B_sm = [1 0 1 0 1 1 0 0 1];
    X = [0 1 1 0 0 0 0 1 1];
    Z = sm_adder(A_sm,B_sm,1)*1;
    t = convert_10base(Z);
    assert(A,B,'-',t,A_sm,B_sm,Z,X);

    % --+
    %disp('--+');
    A = -89;
    A_sm = [1 0 1 0 1 1 0 0 1];
    B = 106;
    B_sm = [0 0 1 1 0 1 0 1 0];
    X = [1 1 1 0 0 0 0 1 1];
    Z = sm_adder(A_sm,B_sm,1)*1;
    t = convert_10base(Z);
    assert(A,B,'-',t,A_sm,B_sm,Z,X);
    
    A = -106;
    A_sm = [1 0 1 1 0 1 0 1 0];
    B = 89;
    B_sm = [0 0 1 0 1 1 0 0 1];
    X = [1 1 1 0 0 0 0 1 1];
    Z = sm_adder(A_sm,B_sm,1)*1;
    t = convert_10base(Z);
    assert(A,B,'-',t,A_sm,B_sm,Z,X);

    % ---
    %disp('---');
    A = -89;
    A_sm = [1 0 1 0 1 1 0 0 1];
    B = -106;
    B_sm = [1 0 1 1 0 1 0 1 0];
    X = [0 0 0 0 1 0 0 0 1];
    Z = sm_adder(A_sm,B_sm,1)*1;
    t = convert_10base(Z);
    assert(A,B,'-',t,A_sm,B_sm,Z,X);
    
    A = -106;
    A_sm = [1 0 1 1 0 1 0 1 0];
    B = -89;
    B_sm = [1 0 1 0 1 1 0 0 1];
    X = [1 0 0 0 1 0 0 0 1];
    Z = sm_adder(A_sm,B_sm,1)*1;
    t = convert_10base(Z);
    assert(A,B,'-',t,A_sm,B_sm,Z,X);
end

function [] = assert(A,B,op,Z,A_b,B_b,Z_b,X_b)
    res = 0;
    if(op == '+') 
        res = A+B;
    elseif(op == '-')
        res = A-B;
    else
        disp('unknown operand!');
    end
    
    assertion = res == Z;
    if(assertion)
        fprintf('\tYes: %s %s %s = %s (%d %s %d = %d)\n',mat2str(A_b),op,mat2str(B_b),mat2str(Z_b),A,op,B,Z);
    else
        fprintf('\tNo : %s %s %s = %s, correct is: %s (%d %s %d = %d, correct is: %d)\n',mat2str(A_b),op,mat2str(B_b),mat2str(Z_b),mat2str(X_b),A,op,B,Z,res);
    end
end

function [Y] = convert_10base(X)
    sgn = X(1);
    X = X(2:length(X));
    len = length(X);
    pwr = len-1:-1:0;
    weight = 2.^pwr;
    Y = sum(X.*weight);
    if(sgn == 1)
        Y = -Y;
    end 
end